//
//  UIImage+Category.m
//  HMDemo
//
//  Created by mengxiangyu on 2017/6/21.
//  Copyright © 2017年 mengxiangyu. All rights reserved.
//

#import "UIImage+Category.h"

typedef NS_ENUM(NSInteger, NSPUIImageType)
{
    NSPUIImageType_JPEG,
    NSPUIImageType_PNG,
    NSPUIImageType_Unknown
};
static inline NSPUIImageType NSPUIImageTypeFromData(NSData *imageData)
{
    if (imageData.length > 4) {
        const unsigned char * bytes = [imageData bytes];
        
        if (bytes[0] == 0xff &&
            bytes[1] == 0xd8 &&
            bytes[2] == 0xff)
        {
            return NSPUIImageType_JPEG;
        }
        
        if (bytes[0] == 0x89 &&
            bytes[1] == 0x50 &&
            bytes[2] == 0x4e &&
            bytes[3] == 0x47)
        {
            return NSPUIImageType_PNG;
        }
    }
    
    return NSPUIImageType_Unknown;
}


@implementation UIImage (Category)
//压缩图片至100k以下 quality(0~1024)
+ (NSData *)imageDataCompressWithSourceImageData:(NSData *)imageData compressionQualityOfK:(CGFloat)quality {
    
    // 获取原图流
    NSData *data;
    //    = UIImageJPEGRepresentation(image, 1);
    
    if (quality*1000/imageData.length > 1) { // 图片尺寸小于指定尺寸
        return imageData;
    } else {
        NSString *string = [NSString stringWithFormat:@"%.2f", quality*1000/imageData.length];
        CGFloat compression = [string floatValue];
        
        if (compression < 0.1) {
            compression = 0.1;
        }
        
        //       NSInteger sourceSize = imageData.length/1000;
        UIImage *image = [UIImage imageWithData:imageData];
        
        //        NSData *dataImage = UIImageJPEGRepresentation(image, 1);   // 二进制转图片，图片再转回二进制大小改变了
        //        NSData *data = UIImagePNGRepresentation(image);
        //        XYLog(@"-------------%ld-----------", (long)NSPUIImageTypeFromData(imageData));
        
        // But if we have an image data, we will look at the preffix
        //        if ([imageData length] >= [kPNGSignatureData length]) {
        //            imageIsPng = ImageDataHasPNGPreffix(imageData);
        //        }
        // UIImagePNGRepresentation(image) == nil
        //        if (!imageIsPng) {
        //            data = UIImageJPEGRepresentation(image, compression);
        //        } else {
        //            data = UIImagePNGRepresentation(image);
        //        }
        
        if (NSPUIImageTypeFromData(imageData)==1) {
            data = UIImagePNGRepresentation(image);
        } else {
            data = UIImageJPEGRepresentation(image, compression);
        }
        
        
        
        
        //        int  perMBBytes = 1024*1024;
        //
        //        CGImageRef cgimage = image.CGImage;
        //        size_t bpp = CGImageGetBitsPerPixel(cgimage);
        //        size_t bpc = CGImageGetBitsPerComponent(cgimage);
        //        size_t bytes_per_pixel = bpp / bpc;
        //
        //        long lPixelsPerMB  = perMBBytes/bytes_per_pixel;
        //
        //
        //        long totalPixel = CGImageGetWidth(image.CGImage)*CGImageGetHeight(image.CGImage);
        //
        //
        //        long totalFileMB = totalPixel/lPixelsPerMB;
        //
        //        XYLog(@"bpp = %lu bpc = %ld  bytes_per_pixel = %ld lPixelsPerMB = %ld  totalPixel = %lu", bpp, bpc, bytes_per_pixel, lPixelsPerMB, totalPixel);
        //
        //
        //        XYLog(@"compression = %f sourceSize = %ld  compressionSize = %ld dataImage = %ld", compression, sourceSize, data.length, dataImage.length);
        
        return data;
    }
    
}


#pragma mark - 创建图片POST头部信息
- (NSData *)createParametersDataWithParamaters:(NSDictionary *)parameters
{
    // 生成了头部信息
    NSString        *start = [NSString stringWithFormat:@"--%@", @"AaB03x"];
    NSMutableString *body  = [[NSMutableString alloc] init];
    NSArray         *keys  = [parameters allKeys];
    
    [keys enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSString *key = keys[idx];
        
        [body appendFormat:@"\r\n%@\r\n", start];
        [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key];
        [body appendFormat:@"%@",parameters[key]];
    }];
    
    return [body dataUsingEncoding:NSUTF8StringEncoding];
}

#pragma mark - 创建图片POST尾部信息
- (NSData *)createEndData
{
    NSString *end = [NSString stringWithFormat:@"\r\n--%@--\r\n", @"AaB03x"];
    return [end dataUsingEncoding:NSUTF8StringEncoding];
}

#pragma mark - 生成POST需要的数据格式
- (NSData *)createPostDataWithParameters:(NSDictionary *)parameters pictures:(NSArray *)pictures
{
    if (@"AaB03x" && parameters)
    {
        NSMutableData *postData = [NSMutableData data];
        
        // 添加头
        [postData appendData:[self createParametersDataWithParamaters:parameters]];
        
        // 添加图片
        [pictures enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            if ([obj isKindOfClass:[NSData class]])
            {
                [postData appendData:obj];
            }
        }];
        
        // 添加尾
        [postData appendData:[self createEndData]];
        
        return postData;
    }
    else
    {
        return nil;
    }
}

#pragma mark - 创建PNG格式的图片
NSData * createPNGPicture(NSString *formBoundary, UIImage *image,
                          NSString *name,         NSString *filename)
{
    NSString *start = [NSString stringWithFormat:@"--%@", formBoundary];
    
    // 添加分界线，换行
    NSMutableString *subBody = [[NSMutableString alloc] init];
    [subBody appendFormat:@"\r\n%@\r\n", start];
    [subBody appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n",
     name, filename];
    
    // 声明上传文件的格式
    [subBody appendFormat:@"Content-Type: image/png\r\n\r\n"];
    
    // 图片data
    NSData *imageData = UIImagePNGRepresentation(image);
    
    // 生成图片data
    NSMutableData *tmpData = [NSMutableData data];
    [tmpData appendData:[subBody dataUsingEncoding:NSUTF8StringEncoding]];
    [tmpData appendData:imageData];
    
    return [NSData dataWithData:tmpData];
}

- (void)configRequest:(NSMutableURLRequest **)request parameters:(NSDictionary *)parameters pictures:(NSArray *)pictures
{
    // 获取到了POST包体
    NSMutableData *postData = [NSMutableData data];
    
    // 添加头
    // 生成了头部信息
    NSString        *start = [NSString stringWithFormat:@"--%@", @"AaB03x"];
    NSMutableString *body  = [[NSMutableString alloc] init];
    NSArray         *keys  = [parameters allKeys];
    
    [keys enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSString *key = keys[idx];
        
        [body appendFormat:@"\r\n%@\r\n", start];
        [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key];
        [body appendFormat:@"%@",parameters[key]];
    }];
    [postData appendData:[body dataUsingEncoding:NSUTF8StringEncoding]];
    
    //    [postData appendData:[self createParametersDataWithParamaters:parameters]];
    // 添加图片
    [pictures enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if ([obj isKindOfClass:[NSData class]])
        {
            [postData appendData:obj];
        }
    }];
    // 添加尾
    //    [postData appendData:[self createEndData]];
    NSString *end = [NSString stringWithFormat:@"\r\n--%@--\r\n", @"AaB03x"];
    [postData appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
    
    
    // 配置请求
    NSMutableURLRequest *tmpRequest = *request;
    
    // 设置请求POST包体
    tmpRequest.HTTPBody    = postData;
    tmpRequest.HTTPMethod  = @"POST";
    
    // 设置HTTPHeaderField
    [tmpRequest setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[postData length]]
      forHTTPHeaderField:@"Content-Length"];
    [tmpRequest setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", @"AaB03x"]
      forHTTPHeaderField:@"Content-Type"];
}


#pragma mark - 压缩图片新方案
+ (NSData *)imageDataCompressWithSourceImageData:(NSData *)imageData orImage:(UIImage *)sourceImage {
    UIImage *imageFixed;
    if (imageData) {
        imageFixed = [UIImage imageWithData:imageData];
    } else {
        imageFixed = sourceImage;
    }
    
    
    CGFloat scaleHeightToWidth = imageFixed.size.height / imageFixed.size.width;
    CGSize newSize = CGSizeMake(1224.00, 1224.00*scaleHeightToWidth);
    UIGraphicsBeginImageContext(newSize);
    [imageFixed drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    NSData *data = UIImageJPEGRepresentation(scaledImage, 0.8);
    
    if ([data length] > 300 * 1000) { // 大于300K，继续压缩
        data = UIImageJPEGRepresentation(scaledImage, 0.7);
        if ([data length] > 300 * 1000) {
            data = UIImageJPEGRepresentation(scaledImage, 0.6); // 最低只压缩到0.6，过多会损失严重
            return data;
        } else {
            return data;
        }
    } else {
        return data;
    }
    
}

+ (NSData *)imageDataCompressWithSourceImageData:(NSData *)imageData orImage:(UIImage *)sourceImage compressionQualityOfK:(CGFloat)quality {
    UIImage *imageFixed;
    if (imageData) {
        imageFixed = [UIImage imageWithData:imageData];
    } else {
        imageFixed = sourceImage;
    }
    
    NSLog(@"--当前大小--:%fkb",(float)[UIImageJPEGRepresentation(sourceImage, 1) length]/1024.0f);
    
    
    CGFloat scaleHeightToWidth = imageFixed.size.height / imageFixed.size.width;
    
    CGSize newSize;
    if (imageFixed.size.height < 1224.0) {
        newSize = imageFixed.size;
    } else {
        newSize = CGSizeMake(1224.00, 1224.00*scaleHeightToWidth);
    }
    
    
    UIGraphicsBeginImageContext(newSize);
    [imageFixed drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    NSData *data = UIImageJPEGRepresentation(scaledImage, 0.8);
    
    if ([data length] > quality * 1000) { // 大于300K，继续压缩
        data = UIImageJPEGRepresentation(scaledImage, 0.7);
        if ([data length] > quality * 1000) {
            data = UIImageJPEGRepresentation(scaledImage, 0.6); // 最低只压缩到0.6，过多会损失严重
            
            NSLog(@"当前大小--:%fkb",(float)[data length]/1024.0f);
            
            return data;
        } else {
            
            NSLog(@"当前大小--:%fkb",(float)[data length]/1024.0f);
            return data;
        }
    } else {
        
        NSLog(@"当前大小--:%fkb",(float)[data length]/1024.0f);
        return data;
    }
    
}

+ (UIImage *)scaleImage:(UIImage *)image toKb:(NSInteger)kb {
    
    if (!image) {
        return image;
    }
    if (kb<1) {
        return image;
    }
    
    kb*=1000;
    
    CGFloat compression = 0.9f;
    CGFloat maxCompression = 0.1f;
    NSData *imageData = UIImageJPEGRepresentation(image, compression);
    while ([imageData length] > kb && compression > maxCompression) {
        compression -= 0.1;
        imageData = UIImageJPEGRepresentation(image, compression);
    }
    
    UIImage *imageFixed = image;
    UIImage *scaledImage = image;
    compression = 0.9f;
    maxCompression = 0.1f;
    while ([UIImageJPEGRepresentation(scaledImage,1) length] > kb && compression > maxCompression) {
        compression -= 0.1;
        CGSize newSize = CGSizeMake(image.size.width * compression, image.size.height * compression);
        UIGraphicsBeginImageContext(newSize);
        [imageFixed drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
        scaledImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    
    return scaledImage;
    
    //    NSData *data = UIImageJPEGRepresentation(scaledImage,1);
    
    //    NSLog(@"当前大小:%fkb",(float)[imageData length]/1024.0f);
    //    UIImage *compressedImage = [UIImage imageWithData:imageData];
    //    return compressedImage;
    
    
}

+ (NSData *)scaleDataImage:(UIImage *)image toKb:(NSInteger)kb {
    
    if (!image) {
        return UIImageJPEGRepresentation(image, 1);
    }
    if (kb<1) {
        return UIImageJPEGRepresentation(image, 1);
    }
    
    kb*=1024;
    
    CGFloat compression = 0.9f;
    CGFloat maxCompression = 0.1f;
    NSData *imageData = UIImageJPEGRepresentation(image, compression);
    while ([imageData length] > kb && compression > maxCompression) {
        compression -= 0.1;
        imageData = UIImageJPEGRepresentation(image, compression);
    }
    NSLog(@"当前大小:%fkb",(float)[imageData length]/1024.0f);
    //    UIImage *compressedImage = [UIImage imageWithData:imageData];
    //    return compressedImage;
    
    
    UIImage *imageFixed = image;
    UIImage *scaledImage = image;
    compression = 0.9f;
    maxCompression = 0.1f;
    while ([imageData length] > kb && compression > maxCompression) {
        compression -= 0.1;
        CGSize newSize = CGSizeMake(image.size.width * compression, image.size.height * compression);
        UIGraphicsBeginImageContext(newSize);
        [imageFixed drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
        scaledImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    
    //    return scaledImage;
    
    return UIImageJPEGRepresentation(scaledImage, 1);
    
}



+ (UIImage *)resizImageWithImage:(NSString *)imageName {
    
    UIImage *image = [UIImage imageNamed:imageName];
    //    UIImage *image = [UIImage imageWithName:@"main_badge"];
    UIImage *newImage = [image resizableImageWithCapInsets:UIEdgeInsetsMake(image.size.height * 0.5, image.size.width * 0.5, image.size.height * 0.5, image.size.width * 0.5)];
    return newImage;
}

+ (instancetype)captureWithView:(UIView *)view
{
    // 1.开启上下文
    UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0);
    
    // 2.将控制器view的layer渲染到上下文
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    
    // 3.取出图片
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    
    // 4.结束上下文
    UIGraphicsEndImageContext();
    
    return newImage;
}

+ (UIImage *)imageFromImage:(UIImage *)image inRect:(CGRect)rect {
    CGImageRef sourceImageRef = [image CGImage];
    CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
    CGImageRelease(newImageRef);
    return newImage;
}

#pragma mark-矫正图片的位置
+ (UIImage *)takePhotoImageOrientation:(UIImage *)aImage {
    
    // No-op if the orientation is already correct
    if (aImage.imageOrientation == UIImageOrientationUp)
        return aImage;
    
    // We need to calculate the proper transformation to make the image upright.
    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
    CGAffineTransform transform = CGAffineTransformIdentity;
    
    switch (aImage.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;
            
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;
            
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        default:
            break;
    }
    
    switch (aImage.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
            
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        default:
            break;
    }
    
    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
                                             CGImageGetBitsPerComponent(aImage.CGImage), 0,
                                             CGImageGetColorSpace(aImage.CGImage),
                                             CGImageGetBitmapInfo(aImage.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (aImage.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
            break;
            
        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
            break;
    }
    
    // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return img;
}

#pragma mark 裁剪照片
+ (UIImage *)scaleToSize:(UIImage *)image size:(CGSize)size
{
    //创建一个bitmap的context
    //并把他设置成当前的context
    UIGraphicsBeginImageContext(size);
    //绘制图片的大小
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
    //从当前context中创建一个改变大小后的图片
    UIImage *endImage=UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    return endImage;
}
@end
